package com.liangtian.mdm.system.file.service.impl;

import com.liangtian.mdm.base.utils.ShiroSessionUtils;
import com.liangtian.mdm.dm.common.enums.Flag;
import com.liangtian.mdm.dm.jsp.common.JspUtil;
import com.liangtian.mdm.system.file.dao.SysFileDao;
import com.liangtian.mdm.system.file.model.SysFile;
import com.liangtian.mdm.system.file.service.SysFileService;
import com.liangtian.mdm.system.parameter.service.SysParameterService;
import com.liangtian.mdm.system.user.model.SysUser;
import com.liangtian.mdm.util.ConstantBean;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;

@Service
@Primary
public class SysFileServiceImpl implements SysFileService {

    @Autowired
    SysFileDao sysFileDao;

    @Autowired
    private SysParameterService sysParameterService;

    //@Value("${ConstantBean.CURRENT_SESSION_USER}")
    //private String ConstantBean.CURRENT_SESSION_USER;

    @Override
    public Map<String, Object> insertFile(HttpServletRequest request, Map<String, Object> Fcond) {
        Map<String, Object> resMap = new HashMap<>();
        boolean success = true;
        /*		StringBuffer fileName=new StringBuffer();
         */
        List<String> fileNameLst = new ArrayList<String>();
        try {
            String surveyType = (String) Fcond.get("surveyType"); //方便测试，后期从页面获取所属业务
//			String surveyName=(String)Fcond.get("surveyName");
            String dataId = (String) Fcond.get("dataId");
            String operType = (String) Fcond.get("operType");
            /*			List<String> fileList = (List<String>)Fcond.get("fileList");*/
            String systemCode = sysParameterService.getSysParamValue("systemCode", "");// 获取系统参数filePath，如果返回值为空则默认返回值为"C:/mdmFile"
            //String filePath="C:/mdmFile"; //文件存储路径，后期需要从系统参数中获取
            String filePath = "";//JspUtil.getFilePath();
//			String filePath = sysParameterService.getSysParamValue("");
            if ("WanDa".equals(systemCode)) {
                filePath = JspUtil.getFilePath();
            } else {
                filePath = sysParameterService.getSysParamValue("filePath", "C:/mdmFile");
            }
//			System.out.println(filePath);
            //创建一个通用的多部分解析器
            CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
            //判断 request 是否有文件上传,即多部分请求
            if (multipartResolver.isMultipart(request)) {
                //转换成多部分request
                MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
                //取得request中的所有文件名
                MultiValueMap<String, MultipartFile> map = multiRequest.getMultiFileMap();
                Set<Entry<String, List<MultipartFile>>> mapSet = map.entrySet();
                String keyColumn = null;//附件的列名,如:c_001,c_002
                int count = 0;
                for (Entry<String, List<MultipartFile>> entry : mapSet) {
                    keyColumn = entry.getKey();
                    count = charCount(keyColumn, '_');
                    if (2 == count)
                        keyColumn = keyColumn.substring(0, keyColumn.lastIndexOf("_"));
                    //记录上传过程起始时的时间，用来计算上传时间
                    int pre = (int) System.currentTimeMillis();
                    //取得上传文件
                    //MultipartFile file = entry.getValue().get(0);
                    //--edit by wangyk : 注释掉上面的代码，上面的代码写死了只取第一个，有多个附件不管用
                    for (MultipartFile file : entry.getValue()) {
                        if (file != null) {
                            //取得当前上传文件的文件名称
                            String myFileName = file.getOriginalFilename();
                            /* fileName.append(myFileName).append(",");*/
                            //如果名称不为“”,说明该文件存在，否则说明该文件不存在
                            if (myFileName.trim() != "") {
                                fileNameLst.add(myFileName);
//		                        System.out.println(myFileName);  
                                //定义上传路径 ,增加定义创建年月信息进行分类，避免时间长了后路径下几万甚至更多的文件夹
                                String path = filePath + File.separator
                                        + surveyType + File.separator
                                        + new SimpleDateFormat("yyyyMM").format(new Date()) + File.separator
                                        + dataId + File.separator + myFileName;
                                //创建目标文件夹
                                (new File(path)).mkdirs();
                                File localFile = new File(path);
                                file.transferTo(localFile);
                                this.insertFileInfo(myFileName, path, file.getSize(), surveyType, dataId, keyColumn, operType);
                            }
                        }
                    }


                    //记录上传该文件后的时间
                    int finaltime = (int) System.currentTimeMillis();
                    System.out.println(finaltime - pre);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            success = false;
        }
        resMap.put("IsSuccess", success);
        resMap.put("FileNameLst", fileNameLst);
        return resMap;
    }

    private Integer charCount(String key, char c) {
        char[] chars = key.toCharArray();
        int count = 0;
        for (int i = 0; i < chars.length; i++) {
            if (c == chars[i])
                count++;
        }
        return count;
    }

    /**
     * 插入附件信息
     *
     * @param fileName
     * @param path
     * @param fileSize
     * @param surveyType
     */
    private void insertFileInfo(String fileName, String path, long fileSize, String surveyType, String dataId, String keyColumn, String operType) {
        //获取列名
        SysFile sysFile = new SysFile();
        SysUser user = ShiroSessionUtils.getSessionSysUser(ConstantBean.CURRENT_SESSION_USER);
        sysFile.setCreator(String.valueOf(user.getUserId()));
        sysFile.setFileName(fileName);
        sysFile.setFileType(fileName.substring(fileName.lastIndexOf(".")));
        sysFile.setFilePath(path);
        sysFile.setFileSize(fileSize + "");
        sysFile.setSurveyType(surveyType);
        sysFile.setDataId(dataId);
        sysFile.setFileColumn(keyColumn);//--把列名保存进去
        sysFile.setOperType(operType);
        sysFileDao.insertSysFile(sysFile);
    }

    @Override
    public List<SysFile> queryFileBySurvey(Map<String, Object> param) {
        return sysFileDao.queryFileBySurvey(param);
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    @Override
    public PageInfo queryFilesPageBySurvey(Map<String, Object> param) {
        PageInfo<List<SysFile>> pageInfo = null;
        try {
            Object pNo = param.get("pageNum");
            int pageNum, pageSize;
            // export
            if (pNo != null && !"NaN".equals(pNo)) {
                pageNum = Integer.parseInt(pNo.toString());// 页码
            } else {
                pageNum = 1;
            }
            // pageSize=0时不分页
            pageSize = Integer.parseInt(param.get("limit").toString());// 模型定义页面要显示数据条数
            // 例如
            // 10,20,50,100
            PageHelper.startPage(pageNum, pageSize);// 开始分页标志（当前页，显示条数）

            String operType = (String) param.get("operType");
            if (Flag.OPER_2.getDesc().equals(operType))
                param.put("operType", Flag.OPER_2.getCode());//审核
            else if (Flag.OPER_1.getDesc().equals(operType))
                param.put("operType", Flag.OPER_1.getCode());//变更
            else if (Flag.OPER_3.getDesc().equals(operType))
                param.put("operType", Flag.OPER_3.getCode());//冻结
            else if (Flag.OPER_4.getDesc().equals(operType))
                param.put("operType", Flag.OPER_4.getCode());//解冻
            else if ("list".equals(operType))
                param.put("operType", "apply");
            List<SysFile> filesList = sysFileDao.queryFileBySurvey(param);
            pageInfo = new PageInfo(filesList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return pageInfo;
    }


    @Override
    public SysFile queryFileById(String id) {
        return sysFileDao.queryFileById(id);
    }


    @Override
    public void delFileByPath(SysFile sFile) {
        String filePath = sFile.getFilePath().substring(0, sFile.getFilePath().lastIndexOf("/"));
        File file = new File(filePath);
        if (file.exists()) {
            deleteFile(file);//删除文件夹下的文件
        }
        sysFileDao.fileDel(sFile.getId());//删除附件表的信息
    }


    @Override
    public void delFileByPath(List<SysFile> sFile) {
        for (int i = 0; i < sFile.size(); i++) {
            SysFile sysFile = sFile.get(i);
            //String filePath=sysFile.getFilePath().substring(0, sysFile.getFilePath().lastIndexOf("/"));
            File file = new File(sysFile.getFilePath());
            if (file.exists()) {
                deleteFile(file);//删除文件夹下的文件
            }
            sysFileDao.fileDel(sysFile.getId());//删除附件表的信息
        }


    }

    /**
     * 递归循环删除文件夹下面的目录及文件
     *
     * @param file
     */
    private static void deleteFile(File file) {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) {
                deleteFile(files[i]);
            }
        }
        file.delete();
    }


    @SuppressWarnings({"rawtypes", "unchecked"})
    @Override
    public PageInfo getCodeXzFjById(Map<String, Object> map) {
        PageInfo<List<SysFile>> pageInfo = null;
        try {
            Object pNo = map.get("pageNum");
            int pageNum, pageSize;
            // export
            if (pNo != null && !"NaN".equals(pNo)) {
                pageNum = Integer.parseInt(pNo.toString());// 页码
            } else {
                pageNum = 1;
            }
            // pageSize=0时不分页
            pageSize = Integer.parseInt(map.get("limit").toString());// 模型定义页面要显示数据条数
            // 例如
            // 10,20,50,100
            PageHelper.startPage(pageNum, pageSize);// 开始分页标志（当前页，显示条数）
            List<SysFile> list = sysFileDao.queryFileBySurvey(map);
            pageInfo = new PageInfo(list);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return pageInfo;
    }

    @Override
    public List<SysFile> queryFileByCond(Map<String, Object> cond) {
        return sysFileDao.queryFileByCond(cond);
    }

    @Override
    public List<SysFile> queryFilesBySurvey(Map<String, Object> param) {
        return sysFileDao.queryFilesBySurvey(param);
    }

    @SuppressWarnings("unchecked")
    @Override
    public Map<String, Object> insertSysContentFile(HttpServletRequest request, Map<String, Object> Fcond) {
        Map<String, Object> resMap = new HashMap<>();
        boolean success = true;
        List<String> fileNameLst = new ArrayList<String>();
        try {
            String surveyType = (String) Fcond.get("surveyType"); //方便测试，后期从页面获取所属业务
            String surveyName = (String) Fcond.get("surveyName");
            String dataId = (String) Fcond.get("dataId");
            String operType = (String) Fcond.get("operType");
            List<String> fileList = (List<String>) Fcond.get("fileList");
//			String filePath="C:/mdmFile"; //文件存储路径，后期需要从系统参数中获取
            String filePath = sysParameterService.getSysParamValue("filePath", "C:/mdmFile");
            //创建一个通用的多部分解析器
            CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
            //判断 request 是否有文件上传,即多部分请求
            if (multipartResolver.isMultipart(request)) {
                //转换成多部分request
                MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
                //取得request中的所有文件名
                MultiValueMap<String, MultipartFile> map = multiRequest.getMultiFileMap();
                Set<Entry<String, List<MultipartFile>>> mapSet = map.entrySet();
                for (Entry<String, List<MultipartFile>> entry : mapSet) {
                    //记录上传过程起始时的时间，用来计算上传时间
                    int pre = (int) System.currentTimeMillis();
                    //取得上传文件
                    MultipartFile file = entry.getValue().get(0);
                    if (file != null) {
                        //取得当前上传文件的文件名称
                        String myFileName = file.getOriginalFilename();
                        String keyColumn = fileList.get(0).trim();//赋值的是版本号
                        /* fileName.append(myFileName).append(",");*/
                        //如果名称不为“”,说明该文件存在，否则说明该文件不存在
                        if (myFileName.trim() != "") {
                            fileNameLst.add(myFileName);
                            //System.out.println(myFileName);
                            //定义上传路径
                            String path = filePath + "/" + surveyName + "/" + new Date().getTime() + "/" + myFileName;
                            //创建目标文件夹
                            (new File(path)).mkdirs();
                            File localFile = new File(path);
                            file.transferTo(localFile);
                            this.insertFileInfo(myFileName, path, file.getSize(), surveyType, dataId, keyColumn, operType);
                        }
                    }
                    //记录上传该文件后的时间
                    int finaltime = (int) System.currentTimeMillis();
                    System.out.println(finaltime - pre);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            success = false;
        }
        resMap.put("IsSuccess", success);
        resMap.put("FileNameLst", fileNameLst);
        return resMap;
    }


}
